package com.cf.core.stage;

import com.cf.Event;
import com.cf.core.event.HeartbeatEvent;
import com.cf.core.event.TicketEvent;
import com.cf.timer.HeartBeatTask;
import com.cf.timer.StageTimingWheel;
import lombok.extern.slf4j.Slf4j;

/**
 * game-server-TimeStage
 * 具有心跳功能的一个场景
 *
 * @author <a href="2428922347@qq.com">Zhu mingming</a>
 * @info
 * @since 2018/4/28 下午 04:10
 */
@Slf4j
public abstract class HeartBeatStage extends Stage {

    private Integer heartBeatStep = 1;

    public HeartBeatStage(int heartBeatStep, int stageTime, String stageNum) {
        super(stageTime, stageNum);
        this.heartBeatStep = heartBeatStep;
    }


    {
        addHeartBeatTask();
    }


    protected HeartBeatTask getHeartBeatTask() {
        return new HeartBeatTask(this.heartBeatStep, this) {

            @Override
            public String getTaskDispatchId() {
                return this.getStage().getStageNum();
            }

            @Override
            protected void doTask() {
                try {
                    if (!this.getStage().end) {
                        this.getStage().broadcastEvent(new TicketEvent());
                    }
                } catch (Exception e) {
                    log.error("处理心跳消息发生异常！", e);
                } finally {
                    if (heartBeatStep > 0 && !this.getStage().end) {
                        log.info("注册下一个心跳！游戏剩余时间为【{}】", this.getStage().getStageLeftTime());
                        addHeartBeatTask();
                    }
                }

            }
        };
    }

    private void addHeartBeatTask() {
        HeartBeatTask heartBeatTask = getHeartBeatTask();
        StageTimingWheel.addTask(heartBeatTask, heartBeatTask.getBeatStepSecond());
    }

    @Override
    public void handle(Event event) {
        if (event instanceof TicketEvent) {
            handleTicketEvent((TicketEvent) event);
        } else {
            handleEvent(event);
        }
    }

    protected abstract void handleEvent(Event event);

    protected abstract void handleTicketEvent(TicketEvent event);
}
